#pragma once

#include <cstring>
#include <string>
#include <cassert>
#include <functional>  

namespace ThreadNs{
    typedef std::function<void*(void*)> func_t;  // 函数指针
    const int num = 1024;
    // #define NUM 1024

    class Thread{
    private:
        // 在类内创建线程，想让线程执行对应的方法，需要将方法设置成为static
        static void* start_routine(void* args){  // 类内成员，有缺省参数！
            Thread* _this = static_cast<Thread*>(args);
            return _this->callback();
        }

    public:
        Thread(){
            char namebuffer[num];
            snprintf(namebuffer, sizeof(namebuffer), "thread-%d",threadnum++);
            name_ = namebuffer;
        }

        void start(func_t func, void* args = nullptr){
            func_ = func;
            args_ = args;
            int n = pthread_create(&tid_, nullptr, start_routine, this);
            assert(n == 0);
            (void)n;
        }

        void join(){
            int n = pthread_join(tid_, nullptr);
            assert(n == 0);
            (void)n;
        }

        std::string threadname(){
            return name_;
        }

        void* callback(){
            return func_(args_);
        }

    private:
        std::string name_;
        func_t func_;  
        void* args_;
        pthread_t tid_;

        static int threadnum;  // 奇数这是第几个线程
    };

    int Thread::threadnum = 1;
} // end namespace ThreadNs
